package com.zg.autoflow.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.utils.MT;
import com.utils.RT;
import com.xn.fastxls.InfoException;
import com.zg.autoflow.dao.mapper.WorkflowInstanceMapper;
import com.zg.autoflow.req.*;
import com.zg.autoflow.service.*;
import com.zg.autoflow.util.FileDown;
import com.zg.autoflow.util.PdfUtils;
import com.zg.autoflow.util.Word2PdfUtilExtend;
import com.zg.autoflow.vo.*;
import com.zg.common.core.A;
import com.zg.common.core.User;
import com.zg.common.core.constant.FlowContants;
import com.zg.common.core.dao.autoflow.dao.*;
import com.zg.common.core.dao.autoflow.entity.*;
import com.zg.common.core.dao.autoform.*;
import com.zg.common.core.exception.BusinessException;
import com.zg.common.core.util.CollectionUtils;
import com.zg.common.core.util.IdUtil;
import com.zg.common.lock.service.LockService;
import com.zg.common.web.Req;
import com.zg.common.web.service.MinioService;
import jodd.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


/**
* @author zg
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class WorkflowManageServiceImpl implements WorkflowManageService {

    private final SettleWorkflowDao settleWorkflowDao;
    private final SettleWorkflowStepDao settleWorkflowStepDao;
    private final SettleWorkflowInstanceDao settleWorkflowInstanceDao;
    private final SettleWorkflowStepInstanceDao settleWorkflowStepInstanceDao;
    private final SettleWorkflowInstanceService settleWorkflowInstanceService;
    private final SettleWorkflowStepInstanceService settleWorkflowStepInstanceService;
    private final SettleWorkflowStepInstUserDao settleWorkflowStepInstUserDao;
    private final SettleWorkflowInstanceLinkDao settleWorkflowInstanceLinkDao;
    private final SettleBizformDao settleBizformDao;
    private final LockService lockService;
    private final SettleWorkflowInstanceWaitstartDao settleWorkflowInstanceWaitstartDao;
    private final AutoflowExtSelNextConfigService autoflowExtSelNextConfigService;
    private final SettleWorkflowStepUserDao settleWorkflowStepUserDao;
    private final SettleWorkflowStepService settleWorkflowStepService;
    private final DiyFormDao formDao;
    private final AutoflowMainDao autoflowMainDao;
    private final AutoflowStepDao autoflowStepDao;
    private final WorkflowInstanceMapper workflowInstanceMapper;
    private final SettleBizmodelDao settleBizmodelDao;
    private final AutoflowStepFormDao autoflowStepFormDao;
    private final MinioService minioService;
    private final DiyFormDao diyFormDao;
    private final DiyTmplDao diyTmplDao;
    private final DiyTmplFileDao diyTmplFileDao;
    private final DiyColumnDao diyColumnDao;
    private final NamedParameterJdbcTemplate jdbcTemplate;
    private final SettleWorkflowBackApprovalDao settleWorkflowBackApprovalDao;

    @Value("${minio.endpoint}")
    private String excelModelRemotePath;

    @Override
    public WorkflowVo startWorkflow(StartWorkflowReq startWorkflowReq) {
        List<SettleWorkflowInstance> prevInstList = new ArrayList<>();
        if (!startWorkflowReq.getBeforeInstCodes().isEmpty()) {
            LambdaQueryWrapper<SettleWorkflowInstance> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(SettleWorkflowInstance::getInstCode, startWorkflowReq.getBeforeInstCodes());
            prevInstList = settleWorkflowInstanceDao.list(queryWrapper);
            if (!prevInstList.isEmpty()) {
                Set<String> flowCodeSet = prevInstList.stream().map(SettleWorkflowInstance::getFlowCode).collect(Collectors.toSet());
                if (flowCodeSet.size() > 1) {
                    BusinessException.happen("您只能一起启动同样的前置流程。当前选择的前置流程不同，无法启动。");
                }
            }
        }

        SettleWorkflow settleWorkflow = settleWorkflowDao.getOne(new LambdaQueryWrapper<SettleWorkflow>().eq(SettleWorkflow::getFlowCode, startWorkflowReq.getFlowCode()).eq(SettleWorkflow::getDeleteState,"0"));
        if (settleWorkflow == null) {
            BusinessException.happen("流程数据错误 请联系管理员");
        }
        SettleWorkflowStep settleWorkflowStep = settleWorkflowStepDao.getOne(new LambdaQueryWrapper<SettleWorkflowStep>().eq(SettleWorkflowStep::getFlowCode, startWorkflowReq.getFlowCode()).eq(SettleWorkflowStep::getStepCode, startWorkflowReq.getStartStep()));
        if (settleWorkflowStep == null) {
            BusinessException.happen("流程数据错误 请联系管理员");
        }

        User loginUser = Req.getCurrUser();

        //生成流程实例
        SettleWorkflowInstance settleWorkflowInstance = new SettleWorkflowInstance();
        settleWorkflowInstance.setInstCode(settleWorkflowInstanceService.createInsCode());
        settleWorkflowInstance.setCreateDate(new Date());
        settleWorkflowInstance.setFlowInstState(FlowContants.FLOW_INST_STATUS_NOSTART);
        //TODO 落登录人组织
//		settleWorkflowInstance.setCreateOrgId(loginUser.getOrgId());
        settleWorkflowInstance.setFlowCode(settleWorkflow.getFlowCode());
        settleWorkflowInstance.setFlowName(settleWorkflow.getFlowName());
        settleWorkflowInstance.setCurrStepOperator(loginUser.getId().toString());
        settleWorkflowInstance.setFlowInstCreator(loginUser.getId().toString());
        //TODO 流程编号生成
        settleWorkflowInstance.setInstanceNo(settleWorkflowInstance.getInstCode());

        //生成环节实例
        SettleWorkflowStepInstance settleWorkflowStepInstance = settleWorkflowStepInstanceService.createStepInstanceByCfg(settleWorkflowInstance, settleWorkflowStep);
        //TODO 落登录人组织
//		settleWorkflowStepInstance.setOperOrg(loginUser.getOrgId());
        settleWorkflowStepInstance.setOperUser(loginUser.getId().toString());
//		settleWorkflowStepInstance.setOperRole(loginUser.getRoleCode());
        settleWorkflowStepInstance.setStepInstState(FlowContants.STEP_INST_STATUS_RUNING);

        settleWorkflowInstance.setCurStep(settleWorkflowStepInstance);

        //创建处理人实例
        SettleWorkflowStepInstUser settleWorkflowStepInstUser = new SettleWorkflowStepInstUser();
        settleWorkflowStepInstUser.setFlowInstCode(settleWorkflowInstance.getInstCode());
        settleWorkflowStepInstUser.setStepInstCode(settleWorkflowStepInstance.getStepInstCode());
        settleWorkflowStepInstUser.setUserId(loginUser.getId().toString());
        settleWorkflowStepInstUser.setDeleteState("0");

        //后置流程启动落前后置关联表
        List<SettleWorkflowInstanceLink> settleWorkflowInstanceLinks = new ArrayList<>();
        if (startWorkflowReq.getBeforeInstCodes() != null && startWorkflowReq.getBeforeInstCodes().size() > 0) {
            for (String befinsid : startWorkflowReq.getBeforeInstCodes()) {
                SettleWorkflowInstanceLink filink = new SettleWorkflowInstanceLink();
                filink.setFromInstCode(befinsid);
                filink.setToInstCode(settleWorkflowInstance.getInstCode());
                settleWorkflowInstanceLinks.add(filink);
            }
        }

        //落库
        settleWorkflowInstanceDao.save(settleWorkflowInstance);
        settleWorkflowStepInstanceDao.save(settleWorkflowStepInstance);
        settleWorkflowStepInstUserDao.save(settleWorkflowStepInstUser);
        if (settleWorkflowInstanceLinks.size() > 0) {
            settleWorkflowInstanceLinkDao.saveBatch(settleWorkflowInstanceLinks);
        }

        WorkflowVo workflowVo = new WorkflowVo(settleWorkflowInstance.getInstCode(), settleWorkflowStepInstance.getStepInstCode());
        return workflowVo;
    }

    @Override
    public WorkflowVo submitWorkflow(SubmitWorkflowReq submitWorkflowReq) {
        Boolean locked = false;
        try {
            locked = lockService.tryLock(submitWorkflowReq.getInstCode(), 5, 5*60, TimeUnit.SECONDS);
            if (locked) {
                String userId = Req.getCurrUser().getId().toString();
                //获取流程实例
                SettleWorkflowInstance settleWorkflowInstance = settleWorkflowInstanceDao.getOne(new LambdaQueryWrapper<SettleWorkflowInstance>().eq(SettleWorkflowInstance::getInstCode, submitWorkflowReq.getInstCode()).eq(SettleWorkflowInstance::getDeleteState, FlowContants.DELETE_STATE_UN));
                A.isNotNull(settleWorkflowInstance, "流程实例不存在");
                //获取环节实例
                SettleWorkflowStepInstance curSettleWorkflowStepInstance = settleWorkflowStepInstanceDao.getOne(new LambdaQueryWrapper<SettleWorkflowStepInstance>().eq(SettleWorkflowStepInstance::getStepInstCode, submitWorkflowReq.getStepInstCode()).eq(SettleWorkflowStepInstance::getDeleteState, FlowContants.DELETE_STATE_UN));
                A.isNotNull(curSettleWorkflowStepInstance, "流程环节实例不存在");
                //校验环节实例状态
                if (!curSettleWorkflowStepInstance.getStepInstState().equals(FlowContants.STEP_INST_STATUS_RUNING)) {
                    BusinessException.happen("该环节已完成，请勿重复提交");
                }
                //获取环节实例处理人
                List<SettleWorkflowStepInstUser> curSettleWorkflowStepInstUsers = settleWorkflowStepInstUserDao.list(new LambdaQueryWrapper<SettleWorkflowStepInstUser>().eq(SettleWorkflowStepInstUser::getStepInstCode, curSettleWorkflowStepInstance.getStepInstCode()).eq(SettleWorkflowStepInstUser::getState, FlowContants.USER_HANDLE_STATUS_DOING).eq(SettleWorkflowStepInstUser::getDeleteState, FlowContants.DELETE_STATE_UN));
                A.isNotEmpty(curSettleWorkflowStepInstUsers, "流程环节实例处理人不存在");
                //校验当前登录人是否有权限处理该环节
                Set<String> curStepInstUserIds = curSettleWorkflowStepInstUsers.stream().map(SettleWorkflowStepInstUser::getUserId).collect(Collectors.toSet());
                if (!curStepInstUserIds.contains(userId)) {
                    BusinessException.happen("当前登录人没有权限处理该环节实例");
                }
                //校验环节实例处理人状态
                SettleWorkflowStepInstUser curSettleWorkflowStepInstUser = curSettleWorkflowStepInstUsers.stream().filter(item -> item.getUserId().equals(userId)).findFirst().get();
                if (curSettleWorkflowStepInstUser.getState().equals(FlowContants.USER_HANDLE_STATUS_OVER)) {
                    BusinessException.happen("当前登录人已处理该环节实例");
                }
                //校验入参中下一环节是否合法
                SettleWorkflowStep curSettleWorkflowStep = settleWorkflowStepDao.getOne(new LambdaQueryWrapper<SettleWorkflowStep>().eq(SettleWorkflowStep::getFlowCode, settleWorkflowInstance.getFlowCode()).eq(SettleWorkflowStep::getStepCode, curSettleWorkflowStepInstance.getStepCode()));
                String[] nextStepCodes = curSettleWorkflowStep.getNextStep().split(",");
                if (!Arrays.asList(nextStepCodes).contains(submitWorkflowReq.getNextStepCode())) {
                    BusinessException.happen("您所选环节并不可用范围，请关闭后重试");
                }
                //校验是否必须盖章
                List<SettleBizform> settleBizforms = settleBizformDao.list(new LambdaQueryWrapper<SettleBizform>().eq(SettleBizform::getStepInstCode, curSettleWorkflowStepInstance.getStepInstCode()));
                settleBizforms.forEach(settleBizform->{
                    if( FlowContants.OK_TAG.equals(curSettleWorkflowStep.getMustSeal())) {
                        if(settleBizform.getState() < FlowContants.SETTLE_BIZFORM_STATE_SEALED) {
                            BusinessException.happen("当前环节必须盖章");
                        }
                    }
                });
                //会签环节需要所有人都处理完成流程才会向下流转
                String approveType = curSettleWorkflowStep.getApproveType();
                if (FlowContants.STEP_APPROVAL_TYPE_HUIQIAN.equals(approveType)) {
                    if (curSettleWorkflowStepInstUsers.size() > 1) {
                        curSettleWorkflowStepInstUser.setState(FlowContants.USER_HANDLE_STATUS_OVER);
                        settleWorkflowStepInstUserDao.updateById(curSettleWorkflowStepInstUser);
                        return new WorkflowVo(submitWorkflowReq.getInstCode(), submitWorkflowReq.getStepInstCode(), false);
                    }
                }

                //草稿箱中的流程要修改为进行中
                if (FlowContants.FLOW_INST_STATUS_DRAFT.equals(settleWorkflowInstance.getFlowInstState())) {
                    settleWorkflowInstance.setFlowInstState(FlowContants.FLOW_INST_STATUS_RUNING);
                }

                //如果是初始节点 并且未真正开始的流程 才需要处理 初始化这一步
                if (FlowContants.STEP_CODE_START.equals(curSettleWorkflowStepInstance.getStepCode())  && settleWorkflowInstance.getFlowInstState().equals(FlowContants.FLOW_INST_STATUS_NOSTART) ) {
                    settleWorkflowInstance.setFlowInstState(FlowContants.FLOW_INST_STATUS_RUNING);
                    //查询关联的环节
                    List<SettleWorkflowInstanceLink> list = settleWorkflowInstanceLinkDao.list(new LambdaQueryWrapper<SettleWorkflowInstanceLink>().eq(SettleWorkflowInstanceLink::getToInstCode, settleWorkflowInstance.getInstCode()));
                    //如果有关联环节
                    if (list.size() > 0) {
                        //查询待处理表
                        Set<String> fromInstCode = new HashSet();
                        for (SettleWorkflowInstanceLink e : list) {
                            fromInstCode.add(e.getFromInstCode());
                        }
                        List<SettleWorkflowInstanceWaitstart> waitStarts = settleWorkflowInstanceWaitstartDao.list(new LambdaQueryWrapper<SettleWorkflowInstanceWaitstart>().in(SettleWorkflowInstanceWaitstart::getFlowInstCode, fromInstCode).eq(SettleWorkflowInstanceWaitstart::getState, FlowContants.WAIT_START_STATE_RUNING));
                        //如果未执行的待处理 和要查的数量不一致 说明已经不对了
                        if (waitStarts.size() != fromInstCode.size()) {
                            BusinessException.happen("前置流程已经被处理 请您重新启动");
                        }
                        waitStarts.forEach(waitstart -> waitstart.setState(FlowContants.WAIT_START_STATE_COMPLETE));
                        settleWorkflowInstanceWaitstartDao.updateBatchById(waitStarts);
                    }
                }

                SettleWorkflow settleWorkflow = settleWorkflowDao.getOne(new LambdaQueryWrapper<SettleWorkflow>().eq(SettleWorkflow::getFlowCode, settleWorkflowInstance.getFlowCode()));
                SettleWorkflowStep nextSettleWorkflowStep = settleWorkflowStepDao.getOne(new LambdaQueryWrapper<SettleWorkflowStep>().eq(SettleWorkflowStep::getFlowCode, settleWorkflowInstance.getFlowCode()).eq(SettleWorkflowStep::getStepCode, submitWorkflowReq.getNextStepCode()));
                //跳转结束特殊处理
                String nextFlowCode = settleWorkflow.getNextFlowCode();
                String nextAuthUser = settleWorkflow.getNextAuthUser();
                String stepStart = FlowContants.STEP_CODE_START;
                if(FlowContants.STEP_APPROVAL_TYPE_TIAOZHUANJIESHU.equals(nextSettleWorkflowStep.getApproveType())) {
                    String stepParameter = nextSettleWorkflowStep.getStepParameter();
                    JSONObject stepParameterData = JSON.parseObject(stepParameter);
                    //对下一个流程进行覆盖
                    String NEXT_FLOW = stepParameterData.getString(FlowContants.STEP_PARAMETER_KEY_NEXT_FLOW);
                    String NEXT_FLOW_STEP = stepParameterData.getString(FlowContants.STEP_PARAMETER_KEY_NEXT_FLOW_STEP);
                    String NEXT_FLOW_USER = stepParameterData.getString(FlowContants.STEP_PARAMETER_KEY_NEXT_FLOW_USER);
                    if(StringUtils.isNotBlank(NEXT_FLOW)) {
                        nextFlowCode = NEXT_FLOW;
                    }
                    if(StringUtils.isNotBlank(NEXT_FLOW_STEP)) {
                        stepStart = NEXT_FLOW_STEP;
                    }
                    if(StringUtils.isNotBlank(NEXT_FLOW_USER)) {
                        nextAuthUser = NEXT_FLOW_USER;
                    }
                    //直接到99环节
                    nextSettleWorkflowStep =  settleWorkflowStepDao.getOne(new LambdaQueryWrapper<SettleWorkflowStep>().eq(SettleWorkflowStep::getFlowCode, settleWorkflow.getFlowCode()).eq(SettleWorkflowStep::getStepCode, FlowContants.STEP_CODE_OVER));
                }

                //生成下一环节实例
                SettleWorkflowStepInstance nextSettleWorkflowStepInstance = settleWorkflowStepInstanceService.createStepInstanceByCfg(settleWorkflowInstance, nextSettleWorkflowStep);
                Boolean IsSelfNext = false;
                //下一环节为99环节处理
                if (FlowContants.STEP_CODE_OVER.equals(nextSettleWorkflowStep.getStepCode())) {
                    //修改当前环,实例状态-已办结
                    settleWorkflowInstance.setFlowInstState(FlowContants.FLOW_INST_STATUS_OVER);
                    settleWorkflowInstance.setSuccessTime(new Date());
                    //99就直接完成就可以了
                    nextSettleWorkflowStepInstance.setSuccessTime(new Date());
                    nextSettleWorkflowStepInstance.setStepInstState(FlowContants.FLOW_INST_STATUS_OVER);
                    nextSettleWorkflowStepInstance.setBeforeStepCode(curSettleWorkflowStepInstance.getStepCode());
                    nextSettleWorkflowStepInstance.setBeforeStepInstCode(curSettleWorkflowStepInstance.getStepInstCode());
                    //如果有下一步流程 则向待启动列表中新增记录
                    //zxb 自动选择后续待启动
                    String finalNextFlowCode = null;
                    String finalNextFlowUser = null;
                    String finalNextFlowStep = null;
                    //先取一对多配置
                    AutoflowExtSelNextConfig config = autoflowExtSelNextConfigService.findNextConfig(settleWorkflowInstance);
                    if (config != null) {
                        finalNextFlowCode = config.getNextFlowCode();
                        finalNextFlowUser = config.getNextFlowUser();
                        finalNextFlowStep = FlowContants.STEP_CODE_START;
                    }
                    //没有一对多配置，再取一对一配置
                    if(StrUtil.isBlank(finalNextFlowCode)) {
                        finalNextFlowCode = nextFlowCode;
                        finalNextFlowUser = nextAuthUser;
                        finalNextFlowStep = stepStart;
                    }
                    //存在后置流程
                    if (StrUtil.isNotBlank(finalNextFlowCode)) {
                        SettleWorkflowInstanceWaitstart waitStart = new SettleWorkflowInstanceWaitstart();
                        waitStart.setFlowCode(settleWorkflow.getFlowCode());
                        waitStart.setFlowInstCode(settleWorkflowInstance.getInstCode());
                        waitStart.setFlowType(settleWorkflow.getFlowType());
                        waitStart.setFlowName(settleWorkflow.getFlowName());
                        waitStart.setNextFlowCode(finalNextFlowCode);
                        waitStart.setNextFlowUser(finalNextFlowUser);
                        waitStart.setState(FlowContants.WAIT_START_STATE_RUNING);
                        waitStart.setFlowState(FlowContants.WAIT_START_STATE_RUNING);
                        waitStart.setNextFlowStep(finalNextFlowStep);
                        settleWorkflowInstanceWaitstartDao.save(waitStart);
                    }
                }else {
                    List<SettleWorkflowStepInstUser> nextStepInstUsers = getsFlowStepInstUsers(submitWorkflowReq.getNextUserId(), nextSettleWorkflowStepInstance);
                    if (nextStepInstUsers.size() > 0) {
                        List<String> nextStepUserIds = nextStepInstUsers.stream().map(SettleWorkflowStepInstUser::getUserId).collect(Collectors.toList());
                        if (nextStepUserIds.contains(userId)) {
                            IsSelfNext = true;
                        }
                        settleWorkflowStepInstUserDao.saveBatch(nextStepInstUsers);
                    }
                }

                settleWorkflowInstance.setCurStep(nextSettleWorkflowStepInstance);
                curSettleWorkflowStepInstance.setStepInstState(FlowContants.STEP_INST_STATUS_COMPLETE);
                curSettleWorkflowStepInstance.setSuccessTime(new Date());
                curSettleWorkflowStepInstance.setOperUser(userId);
                //TODO 落操作人组织
//                curSettleWorkflowStepInstance.setOperOrg(orgId);
                curSettleWorkflowStepInstUser.setState("1");
                nextSettleWorkflowStepInstance.setStepInstState(FlowContants.STEP_INST_STATUS_RUNING);
                //落库
                settleWorkflowStepInstanceDao.save(nextSettleWorkflowStepInstance);
                settleWorkflowInstanceDao.updateById(settleWorkflowInstance);
                settleWorkflowStepInstanceDao.updateById(curSettleWorkflowStepInstance);
                settleWorkflowStepInstUserDao.updateById(curSettleWorkflowStepInstUser);
                return new WorkflowVo(submitWorkflowReq.getInstCode(), nextSettleWorkflowStepInstance.getStepInstCode(), IsSelfNext);
            }
        }catch (Exception e) {
            e.printStackTrace();
            throw  e;
        }finally {
            if (locked) {
                lockService.unlock(submitWorkflowReq.getInstCode());
            }
        }
        return null;
    }

    public List<SettleWorkflowStepInstUser> getsFlowStepInstUsers(String next_user_id, SettleWorkflowStepInstance nextStepIns) {
        //下一步的执行人列表
        List<SettleWorkflowStepInstUser> flowStepInstUsers = new ArrayList<>();
        if (StringUtil.isNotBlank(next_user_id)) {
            String[] split = next_user_id.split(",");
            for (String userid :split   ) {
                SettleWorkflowStepInstUser flowStepInstUser = new SettleWorkflowStepInstUser();
                flowStepInstUser.setFlowInstCode(nextStepIns.getInstCode());
                flowStepInstUser.setStepInstCode(nextStepIns.getStepInstCode());
                flowStepInstUser.setDeleteState("0");
                flowStepInstUser.setUserId(userid);
                flowStepInstUsers.add(flowStepInstUser);
            }
        }else {//未指定就是所有可见的人员都可见
            List<SettleWorkflowStepUser> stepUser = settleWorkflowStepUserDao.list(new LambdaQueryWrapper<SettleWorkflowStepUser>().eq(SettleWorkflowStepUser::getFlowCode, nextStepIns.getFlowCode()).eq(SettleWorkflowStepUser::getStepCode, nextStepIns.getStepCode()));
            for (SettleWorkflowStepUser user : stepUser) {
                SettleWorkflowStepInstUser flowStepInstUser = new SettleWorkflowStepInstUser();
                flowStepInstUser.setFlowInstCode(nextStepIns.getInstCode());
                flowStepInstUser.setStepInstCode(nextStepIns.getStepInstCode());
                flowStepInstUser.setDeleteState("0");
                flowStepInstUser.setUserId(user.getOperUser());
                flowStepInstUsers.add(flowStepInstUser);
            }
        }
        return flowStepInstUsers;
    }

    @Override
    public String backWorkflow(BackWorkflowReq backWorkflowReq) {
        Boolean locked = false;
        try {
            locked = lockService.tryLock(backWorkflowReq.getCurInstCode(), 5, 5 * 60, TimeUnit.SECONDS);
            if (locked) {
                String userId = Req.getCurrUser().getId().toString();
                SettleWorkflowInstance curSettleWorkflowInstance = settleWorkflowInstanceDao.getOne(new LambdaQueryWrapper<SettleWorkflowInstance>().eq(SettleWorkflowInstance::getInstCode, backWorkflowReq.getCurInstCode()));
                A.isNotNull(curSettleWorkflowInstance, "未查询到当前流程实例信息！");
                List<SettleWorkflowStepInstance> curSettleWorkflowStepInstanceList = settleWorkflowStepInstanceDao.list(new LambdaQueryWrapper<SettleWorkflowStepInstance>().eq(SettleWorkflowStepInstance::getInstCode, backWorkflowReq.getCurInstCode()));
                A.isNotEmpty(curSettleWorkflowStepInstanceList, "未查询到当前流程的环节实例信息！");
                SettleWorkflowStepInstance curSettleWorkflowStepInstance = curSettleWorkflowStepInstanceList.stream().filter(step -> step.getStepInstCode().equals(backWorkflowReq.getCurStepInstCode())).collect(Collectors.toList()).get(0);
                A.isNotNull(curSettleWorkflowStepInstance, "未查询到当前环节实例信息！");
                if (!curSettleWorkflowStepInstance.getStepInstState().equals(FlowContants.STEP_INST_STATUS_RUNING)) {
                    BusinessException.happen("当前环节不是处理中的状态，无法退回！");
                }
                Map<String, SettleWorkflowStep> curFlowAllStepMap = settleWorkflowStepService.getFlowAllStepMap(curSettleWorkflowInstance.getFlowCode());
                A.isNotEmpty(curFlowAllStepMap, "未查询到当前流程环节配置信息！");
                SettleWorkflowStep curSettleWorkflowStep = curFlowAllStepMap.get(curSettleWorkflowStepInstance.getStepCode());
                A.isNotNull(curSettleWorkflowStep, "未查询到当前环节配置信息！");
                if (!curSettleWorkflowStep.getCanBack().equals(FlowContants.OK_TAG)) {
                    BusinessException.happen("当前环节不可进行退回操作！");
                }
//                List<SettleWorkflowStepInstUser> curSettleWorkflowStepInstUsers = settleWorkflowStepInstUserDao.list(new LambdaQueryWrapper<SettleWorkflowStepInstUser>().eq(SettleWorkflowStepInstUser::getStepInstCode, curSettleWorkflowStepInstance.getStepInstCode()).eq(SettleWorkflowStepInstUser::getState, FlowContants.USER_HANDLE_STATUS_DOING).eq(SettleWorkflowStepInstUser::getDeleteState, FlowContants.DELETE_STATE_UN));
//                A.isNotEmpty(curSettleWorkflowStepInstUsers, "未查询到当前环节处理人实例信息！");
//                Set<String> curStepInstUserIds = curSettleWorkflowStepInstUsers.stream().map(SettleWorkflowStepInstUser::getUserId).collect(Collectors.toSet());
//                if (!curStepInstUserIds.contains(userId)) {
//                    BusinessException.happen("当前登录人没有权限处理该环节实例");
//                }

                String[] backStepInstCodes = backWorkflowReq.getBackStepInstCodes().split(",");
                String[] backDescs = backWorkflowReq.getBackDescs().split(",");

                //退回至当前流程
                if (backStepInstCodes.length == 1 && curSettleWorkflowStepInstanceList.stream().map(SettleWorkflowStepInstance::getStepInstCode).collect(Collectors.toList()).contains(backStepInstCodes[0])) {
                    SettleWorkflowStepInstance backSettleWorkflowStepInstance = curSettleWorkflowStepInstanceList.stream().filter(step -> step.getStepInstCode().equals(backStepInstCodes[0])).collect(Collectors.toList()).get(0);
                    A.isNotNull(backSettleWorkflowStepInstance, "未查询到退回环节实例信息！");
                    if (!backSettleWorkflowStepInstance.getStepInstState().equals(FlowContants.STEP_INST_STATUS_COMPLETE)) {
                        BusinessException.happen("该退回环节实例不是已完成状态，无法退回！");
                    }
                    SettleWorkflowStep backSettleWorkflowStep = curFlowAllStepMap.get(backSettleWorkflowStepInstance.getStepCode());
                    A.isNotNull(backSettleWorkflowStep, "未查询到退回环节配置信息！");
                    if (!FlowContants.OK_TAG.equals(backSettleWorkflowStep.getCanBeBack())) {
                        BusinessException.happen("该退回环节不可被退回！");
                    }

                    List<SettleWorkflowStepInstUser> backSettleWorkflowStepInstUsers = settleWorkflowStepInstUserDao.list(new LambdaQueryWrapper<SettleWorkflowStepInstUser>().eq(SettleWorkflowStepInstUser::getStepInstCode, backStepInstCodes[0]));
                    A.isNotEmpty(backSettleWorkflowStepInstUsers, "未查询到退回环节处理人实例信息！");
                    //退回审批
                    if ("1".equals(curSettleWorkflowStep.getIsBackApproval()) && !"1".equals(backWorkflowReq.getApprovalFlag())){
                        SettleWorkflowBackApproval approvalIng = settleWorkflowBackApprovalDao.getOne(new LambdaQueryWrapper<SettleWorkflowBackApproval>().eq(SettleWorkflowBackApproval::getInstCode,backWorkflowReq.getCurInstCode()));
                        if (ObjectUtils.isNotEmpty(approvalIng)) {
                            throw new InfoException("退回审批中，请勿重复操作！");
                        }else {
                            //插入退回审批表
                            SettleWorkflowBackApproval settleWorkflowBackApproval = new SettleWorkflowBackApproval();
                            settleWorkflowBackApproval.setInstCode(backWorkflowReq.getCurInstCode());
                            if (ObjectUtils.isNotEmpty(curSettleWorkflowStepInstance)) {
                                settleWorkflowBackApproval.setCurrStepInstCode(curSettleWorkflowStepInstance.getStepInstCode());
                                settleWorkflowBackApproval.setCurrStepCode(curSettleWorkflowStepInstance.getStepCode());
                                settleWorkflowBackApproval.setCurrStepName(curSettleWorkflowStepInstance.getStepName());
                            }
                            settleWorkflowBackApproval.setCurrStepUser(userId);
                            settleWorkflowBackApproval.setBackStepInstCode(backWorkflowReq.getBackStepInstCodes());
                            settleWorkflowBackApproval.setBackStepCode(backSettleWorkflowStepInstance.getStepCode());
                            settleWorkflowBackApproval.setBackStepName(backSettleWorkflowStepInstance.getStepName());
                            settleWorkflowBackApproval.setBackStepUser(backSettleWorkflowStepInstance.getOperUser());
                            settleWorkflowBackApproval.setApprovalStatus("0");
                            settleWorkflowBackApproval.setBackReason(backDescs[0]);
                            settleWorkflowBackApprovalDao.save(settleWorkflowBackApproval);
                            return "退回申请已发出，待同意后退回完成";
                        }
                    }else {
                        //更新当前环节退回描述
                        curSettleWorkflowStepInstance.setStepDesc(backDescs[0]);
                        settleWorkflowStepInstanceDao.updateById(curSettleWorkflowStepInstance);

                        //修改最后一个环节至退回环节的环节状态为已退回
                        LambdaUpdateWrapper<SettleWorkflowStepInstance> settleWorkflowStepInstanceLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                        settleWorkflowStepInstanceLambdaUpdateWrapper.eq(SettleWorkflowStepInstance::getInstCode, backWorkflowReq.getCurInstCode());
                        settleWorkflowStepInstanceLambdaUpdateWrapper.ge(SettleWorkflowStepInstance::getId, backSettleWorkflowStepInstance.getId());
                        settleWorkflowStepInstanceLambdaUpdateWrapper.set(SettleWorkflowStepInstance::getStepInstState, FlowContants.STEP_INST_STATUS_RETURNBACK);
                        settleWorkflowStepInstanceDao.update(settleWorkflowStepInstanceLambdaUpdateWrapper);

                        //新建环节实例
                        SettleWorkflowStepInstance newSettleWorkflowStepInstance = settleWorkflowStepInstanceService.createStepInstanceByCfg(curSettleWorkflowInstance, backSettleWorkflowStep);
                        newSettleWorkflowStepInstance.setBeforeStepCode(curSettleWorkflowStepInstance.getStepCode());
                        newSettleWorkflowStepInstance.setBeforeStepInstCode(curSettleWorkflowStepInstance.getStepInstCode());
                        newSettleWorkflowStepInstance.setStepInstState(FlowContants.STEP_INST_STATUS_RUNING);
                        settleWorkflowStepInstanceDao.save(newSettleWorkflowStepInstance);

                        //新建环节处理人实例
                        backSettleWorkflowStepInstUsers.forEach(stepInstUser -> {
                            stepInstUser.setId(null);
                            stepInstUser.setStepInstCode(newSettleWorkflowStepInstance.getStepInstCode());
                            stepInstUser.setState(FlowContants.USER_HANDLE_STATUS_DOING);
                        });
                        settleWorkflowStepInstUserDao.saveBatch(backSettleWorkflowStepInstUsers);

                        //更新流程实例信息
                        curSettleWorkflowInstance.setCurStep(newSettleWorkflowStepInstance);
                        curSettleWorkflowInstance.setCurrStepOperator("");
                        curSettleWorkflowInstance.setFlowInstState(FlowContants.FLOW_INST_STATUS_RUNING);
                        settleWorkflowInstanceDao.updateById(curSettleWorkflowInstance);
                    }
                } else {//退回至前置流程
                    //校验
                    List<SettleWorkflowStepInstance> backSettleWorkflowStepInstances = settleWorkflowStepInstanceDao.list(new LambdaQueryWrapper<SettleWorkflowStepInstance>().in(SettleWorkflowStepInstance::getStepInstCode, backStepInstCodes));
                    A.isNotEmpty(backSettleWorkflowStepInstances,  "未查询到退回环节实例信息！");
                    Map<Object, SettleWorkflowStepInstance> backSettleWorkflowStepInstanceMap = CollectionUtils.collectionToMap(backSettleWorkflowStepInstances, SettleWorkflowStepInstance::getStepInstCode);
                    Set<String> backInstCodes = backSettleWorkflowStepInstances.stream().map(SettleWorkflowStepInstance::getInstCode).collect(Collectors.toSet());
                    List<SettleWorkflowInstance> backSettleWorkflowInstances = settleWorkflowInstanceDao.list(new LambdaQueryWrapper<SettleWorkflowInstance>().in(SettleWorkflowInstance::getInstCode, backInstCodes));
                    A.isNotEmpty(backSettleWorkflowInstances, "未查询到退回流程实例信息！");
                    Map<Object, SettleWorkflowInstance> backSettleWorkflowInstanceMap = CollectionUtils.collectionToMap(backSettleWorkflowInstances, SettleWorkflowInstance::getInstCode);
                    List<SettleWorkflowStepInstance> newSettleWorkflowStepInstances = new ArrayList<>();
                    List<SettleWorkflowStepInstUser> newSettleWorkflowStepInstUsers = new ArrayList<>();
                    for (int i = 0; i < backStepInstCodes.length; i++) {
                        SettleWorkflowStepInstance backSettleWorkflowStepInstance = backSettleWorkflowStepInstanceMap.get(backStepInstCodes[i]);
                        A.isNotNull(backSettleWorkflowStepInstance, "未查询到退回环节实例信息！");
                        if (!backSettleWorkflowStepInstance.getStepInstState().equals(FlowContants.STEP_INST_STATUS_COMPLETE)) {
                            BusinessException.happen("该退回环节实例不是已完成状态，无法退回！");
                        }

                        SettleWorkflowInstance backSettleWorkflowInstance = backSettleWorkflowInstanceMap.get(backSettleWorkflowStepInstance.getInstCode());
                        A.isNotNull(backSettleWorkflowInstance, "未查询到退回流程实例信息！");

                        Map<String, SettleWorkflowStep> backFlowAllStepMap = settleWorkflowStepService.getFlowAllStepMap(backSettleWorkflowInstance.getFlowCode());
                        A.isNotEmpty(backFlowAllStepMap, "未查询到退回流程环节配置信息！");
                        SettleWorkflowStep backSettleWorkflowStep = backFlowAllStepMap.get(backSettleWorkflowStepInstance.getStepCode());
                        A.isNotNull(backSettleWorkflowStep, "未查询到退回环节配置信息！");
                        if (!FlowContants.OK_TAG.equals(backSettleWorkflowStep.getCanBeBack())) {
                            BusinessException.happen("该退回环节不可被退回！");
                        }
                    }

                    //数据处理
                    for (int i = 0; i < backStepInstCodes.length; i++) {
                        SettleWorkflowStepInstance backSettleWorkflowStepInstance = backSettleWorkflowStepInstanceMap.get(backStepInstCodes[i]);
                        //退回审批
                        if ("1".equals(curSettleWorkflowStep.getIsBackApproval()) && !"1".equals(backWorkflowReq.getApprovalFlag())){
                            SettleWorkflowBackApproval approvalIng = settleWorkflowBackApprovalDao.getOne(new LambdaQueryWrapper<SettleWorkflowBackApproval>().eq(SettleWorkflowBackApproval::getInstCode,backWorkflowReq.getCurInstCode()));
                            if (ObjectUtils.isNotEmpty(approvalIng)) {
                                throw new InfoException("退回审批中，请勿重复操作！");
                            }else {
                                //插入退回审批表
                                SettleWorkflowBackApproval settleWorkflowBackApproval = new SettleWorkflowBackApproval();
                                settleWorkflowBackApproval.setInstCode(backWorkflowReq.getCurInstCode());
                                if (ObjectUtils.isNotEmpty(curSettleWorkflowStepInstance)) {
                                    settleWorkflowBackApproval.setCurrStepInstCode(curSettleWorkflowStepInstance.getStepInstCode());
                                    settleWorkflowBackApproval.setCurrStepCode(curSettleWorkflowStepInstance.getStepCode());
                                    settleWorkflowBackApproval.setCurrStepName(curSettleWorkflowStepInstance.getStepName());
                                }
                                settleWorkflowBackApproval.setCurrStepUser(userId);
                                settleWorkflowBackApproval.setBackStepInstCode(backWorkflowReq.getBackStepInstCodes());
                                settleWorkflowBackApproval.setBackStepCode(backSettleWorkflowStepInstance.getStepCode());
                                settleWorkflowBackApproval.setBackStepName(backSettleWorkflowStepInstance.getStepName());
                                settleWorkflowBackApproval.setBackStepUser(backSettleWorkflowStepInstance.getOperUser());
                                settleWorkflowBackApproval.setApprovalStatus("0");
                                settleWorkflowBackApproval.setBackReason(backDescs[i]);
                                settleWorkflowBackApprovalDao.save(settleWorkflowBackApproval);
                                return  "退回申请已发出，待同意后退回完成";
                            }
                        }else {
                            SettleWorkflowInstance backSettleWorkflowInstance = backSettleWorkflowInstanceMap.get(backSettleWorkflowStepInstance.getInstCode());
                            Map<String, SettleWorkflowStep> backFlowAllStepMap = settleWorkflowStepService.getFlowAllStepMap(backSettleWorkflowInstance.getFlowCode());

                            //修改最后一个环节至退回环节的环节状态为已退回
                            LambdaUpdateWrapper<SettleWorkflowStepInstance> settleWorkflowStepInstanceLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                            settleWorkflowStepInstanceLambdaUpdateWrapper.eq(SettleWorkflowStepInstance::getInstCode, backStepInstCodes[i]);
                            settleWorkflowStepInstanceLambdaUpdateWrapper.ge(SettleWorkflowStepInstance::getId, backSettleWorkflowStepInstance.getId());
                            settleWorkflowStepInstanceLambdaUpdateWrapper.set(SettleWorkflowStepInstance::getStepInstState, FlowContants.STEP_INST_STATUS_RETURNBACK);
                            settleWorkflowStepInstanceDao.update(settleWorkflowStepInstanceLambdaUpdateWrapper);

                            //新建前置流程环节
                            List<SettleWorkflowStepInstance> backAllSettleWorkflowStepInstances = settleWorkflowStepInstanceDao.list(new LambdaQueryWrapper<SettleWorkflowStepInstance>().eq(SettleWorkflowStepInstance::getInstCode, backSettleWorkflowInstance.getInstCode()).orderByDesc(SettleWorkflowStepInstance::getCreateDate));
                            SettleWorkflowStepInstance returnSettleWorkflowStepInstance = settleWorkflowStepInstanceService.createStepInstanceByCfg(backSettleWorkflowInstance, backFlowAllStepMap.get(backSettleWorkflowStepInstance.getStepCode()));
                            returnSettleWorkflowStepInstance.setStepCode(FlowContants.STEP_CODE_RETURN);
                            returnSettleWorkflowStepInstance.setStepName("跨流程退回");
                            returnSettleWorkflowStepInstance.setStepDesc(backDescs[i]);
                            returnSettleWorkflowStepInstance.setStepInstState(FlowContants.STEP_INST_STATUS_RETURNBACK);
                            returnSettleWorkflowStepInstance.setBeforeStepCode(backAllSettleWorkflowStepInstances.get(0).getStepCode());
                            newSettleWorkflowStepInstances.add(returnSettleWorkflowStepInstance);
                            SettleWorkflowStepInstance newSettleWorkflowStepInstance = settleWorkflowStepInstanceService.createStepInstanceByCfg(backSettleWorkflowInstance, backFlowAllStepMap.get(backSettleWorkflowStepInstance.getStepCode()));
                            newSettleWorkflowStepInstance.setStepInstState(FlowContants.STEP_INST_STATUS_RUNING);
                            newSettleWorkflowStepInstance.setBeforeStepCode(returnSettleWorkflowStepInstance.getStepCode());
                            newSettleWorkflowStepInstance.setBeforeStepInstCode(returnSettleWorkflowStepInstance.getStepInstCode());
                            newSettleWorkflowStepInstance.setStepDesc(backDescs[i]);
                            newSettleWorkflowStepInstances.add(newSettleWorkflowStepInstance);

                            List<SettleWorkflowStepInstUser> backSettleWorkflowStepInstUsers = settleWorkflowStepInstUserDao.list(new LambdaQueryWrapper<SettleWorkflowStepInstUser>().eq(SettleWorkflowStepInstUser::getStepInstCode, backStepInstCodes[i]));
                            backSettleWorkflowStepInstUsers.forEach(stepInstUser -> {
                                stepInstUser.setId(null);
                                stepInstUser.setStepInstCode(newSettleWorkflowStepInstance.getStepInstCode());
                                stepInstUser.setState(FlowContants.USER_HANDLE_STATUS_DOING);
                            });
                            newSettleWorkflowStepInstUsers.addAll(backSettleWorkflowStepInstUsers);

                            //更新流程实例信息
                            backSettleWorkflowInstance.setCurStep(newSettleWorkflowStepInstance);
                            backSettleWorkflowInstance.setCurrStepOperator("");
                            backSettleWorkflowInstance.setFlowInstState(FlowContants.FLOW_INST_STATUS_RUNING);
                            settleWorkflowInstanceDao.updateById(backSettleWorkflowInstance);
                        }
                        //作废当前流程
                        curSettleWorkflowInstance.setFlowInstState(FlowContants.FLOW_INST_STATUS_CANCEL);
                        settleWorkflowInstanceDao.updateById(curSettleWorkflowInstance);
                        //修改当前流程环节状态为作废
                        curSettleWorkflowStepInstance.setStepInstState(FlowContants.STEP_INST_STATUS_CANCEL);
                        curSettleWorkflowStepInstance.setIsSeal(FlowContants.NO_TAG);
                        curSettleWorkflowStepInstance.setSuccessTime(new Date());
                        settleWorkflowStepInstanceDao.updateById(curSettleWorkflowStepInstance);
                        //删除当前流程环节关联
                        LambdaUpdateWrapper<SettleWorkflowInstanceLink> settleWorkflowInstanceLinkLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                        settleWorkflowInstanceLinkLambdaUpdateWrapper.eq(SettleWorkflowInstanceLink::getToInstCode, curSettleWorkflowInstance.getInstCode());
                        settleWorkflowInstanceLinkLambdaUpdateWrapper.set(SettleWorkflowInstanceLink::getDeleteState, FlowContants.DELETE_STATE_YES);
                        settleWorkflowInstanceLinkDao.update(settleWorkflowInstanceLinkLambdaUpdateWrapper);
                        //处理待启动表，退回的就删除，未退回的就改为待启动
                        LambdaQueryWrapper<SettleWorkflowInstanceLink> settleWorkflowInstanceLinkLambdaQueryWrapper = new LambdaQueryWrapper<>();
                        settleWorkflowInstanceLinkLambdaQueryWrapper.eq(SettleWorkflowInstanceLink::getToInstCode, curSettleWorkflowInstance.getInstCode());
                        List<SettleWorkflowInstanceLink> settleWorkflowInstanceLinks = settleWorkflowInstanceLinkDao.list(settleWorkflowInstanceLinkLambdaQueryWrapper);
                        if (settleWorkflowInstanceLinks.size() > 0) {
                            Set<SettleWorkflowInstanceLink> inSettleWorkflowInstanceLinks = settleWorkflowInstanceLinks.stream().filter(settleWorkflowInstanceLink -> backInstCodes.contains(settleWorkflowInstanceLink.getFromInstCode())).collect(Collectors.toSet());
                            Set<SettleWorkflowInstanceLink> unSettleWorkflowInstanceLinks = settleWorkflowInstanceLinks.stream().filter(settleWorkflowInstanceLink -> !backInstCodes.contains(settleWorkflowInstanceLink.getFromInstCode())).collect(Collectors.toSet());
                            if (!CollectionUtils.isEmpty(inSettleWorkflowInstanceLinks)) {
                                settleWorkflowInstanceWaitstartDao.remove(new LambdaQueryWrapper<SettleWorkflowInstanceWaitstart>().eq(SettleWorkflowInstanceWaitstart::getFlowInstCode, inSettleWorkflowInstanceLinks.stream().map(SettleWorkflowInstanceLink::getFromInstCode).collect(Collectors.toSet())));
                            }
                            if (!CollectionUtils.isEmpty(unSettleWorkflowInstanceLinks)) {
                                LambdaUpdateWrapper<SettleWorkflowInstanceWaitstart> settleWorkflowInstanceWaitstartLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                                settleWorkflowInstanceWaitstartLambdaUpdateWrapper.eq(SettleWorkflowInstanceWaitstart::getFlowInstCode, unSettleWorkflowInstanceLinks.stream().map(SettleWorkflowInstanceLink::getFromInstCode).collect(Collectors.toSet()));
                                settleWorkflowInstanceWaitstartLambdaUpdateWrapper.set(SettleWorkflowInstanceWaitstart::getState, FlowContants.WAIT_START_STATE_RUNING);
                                settleWorkflowInstanceWaitstartDao.update(settleWorkflowInstanceWaitstartLambdaUpdateWrapper);
                            }
                        }
                        //新建前置流程环节
                        settleWorkflowStepInstanceDao.saveBatch(newSettleWorkflowStepInstances);
                        //新建环节处理人实例
                        settleWorkflowStepInstUserDao.saveBatch(newSettleWorkflowStepInstUsers);
                    }
                }
                return "退回成功";
            } else {
                return "正在退回，请勿重复操作";
            }
        } catch (Exception e) {
            e.printStackTrace();
           throw  e;
        }finally {
            if (locked) {
                lockService.unlock(backWorkflowReq.getCurInstCode());
            }
        }
    }

    @Override
    public String cancelWorkflow(CancelWorkflowReq cancelWorkflowReq) {
        Boolean locked = false;
        try {
            locked = lockService.tryLock(cancelWorkflowReq.getInstCode(), 5, 5 * 60, TimeUnit.SECONDS);
            if (locked) {
                String userId = Req.getCurrUser().getId().toString();
                //校验
                SettleWorkflowInstance settleWorkflowInstance = settleWorkflowInstanceDao.getOne(new LambdaQueryWrapper<SettleWorkflowInstance>().eq(SettleWorkflowInstance::getInstCode, cancelWorkflowReq.getInstCode()));
                A.isNotNull(settleWorkflowInstance, "未查询到流程实例信息！");
                //只有流程在第一个环节 才能被作废
                if (!FlowContants.STEP_CODE_START.equals(settleWorkflowInstance.getFlowInstCurrStep())) {
                    BusinessException.happen("此流程不在起始环节，不可以作废");
                }
                //流程没有被作废的情况下才能作废
                if (FlowContants.FLOW_INST_STATUS_CANCEL.equals(settleWorkflowInstance.getFlowInstState())) {
                    BusinessException.happen("此流程已经作废不可以重复作废");
                }
                SettleWorkflowStepInstance settleWorkflowStepInstance = settleWorkflowStepInstanceDao.getOne(new LambdaQueryWrapper<SettleWorkflowStepInstance>().eq(SettleWorkflowStepInstance::getStepInstCode, settleWorkflowInstance.getFlowInstCurrStepInst()));
                A.isNotNull(settleWorkflowStepInstance, "未查询到环节实例信息！");
                List<SettleWorkflowStepInstUser> curSettleWorkflowStepInstUsers = settleWorkflowStepInstUserDao.list(new LambdaQueryWrapper<SettleWorkflowStepInstUser>().eq(SettleWorkflowStepInstUser::getStepInstCode, settleWorkflowStepInstance.getStepInstCode()).eq(SettleWorkflowStepInstUser::getState, FlowContants.USER_HANDLE_STATUS_DOING).eq(SettleWorkflowStepInstUser::getDeleteState, FlowContants.DELETE_STATE_UN));
                A.isNotEmpty(curSettleWorkflowStepInstUsers, "未查询到当前环节处理人实例信息！");
                Set<String> curStepInstUserIds = curSettleWorkflowStepInstUsers.stream().map(SettleWorkflowStepInstUser::getUserId).collect(Collectors.toSet());
                if (!curStepInstUserIds.contains(userId)) {
                    BusinessException.happen("当前登录人没有权限处理该环节实例");
                }

                LambdaQueryWrapper<SettleWorkflowInstanceLink> settleWorkflowInstanceLinkLambdaQueryWrapper = new LambdaQueryWrapper<>();
                settleWorkflowInstanceLinkLambdaQueryWrapper.eq(SettleWorkflowInstanceLink::getToInstCode, settleWorkflowInstance.getInstCode());
                List<SettleWorkflowInstanceLink> settleWorkflowInstanceLinks = settleWorkflowInstanceLinkDao.list(settleWorkflowInstanceLinkLambdaQueryWrapper);
                if (!CollectionUtils.isEmpty(settleWorkflowInstanceLinks)) {
                    LambdaUpdateWrapper<SettleWorkflowInstanceWaitstart> settleWorkflowInstanceWaitstartLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                    settleWorkflowInstanceWaitstartLambdaUpdateWrapper.in(SettleWorkflowInstanceWaitstart::getFlowInstCode, settleWorkflowInstanceLinks.stream().map(SettleWorkflowInstanceLink::getFromInstCode).collect(Collectors.toSet()));
                    settleWorkflowInstanceWaitstartLambdaUpdateWrapper.set(SettleWorkflowInstanceWaitstart::getState, FlowContants.WAIT_START_STATE_RUNING);
                    settleWorkflowInstanceWaitstartDao.update(settleWorkflowInstanceWaitstartLambdaUpdateWrapper);
                }
                settleWorkflowInstance.setFlowInstState(FlowContants.FLOW_INST_STATUS_CANCEL);
                settleWorkflowInstance.setReason(cancelWorkflowReq.getReason());
                settleWorkflowInstanceDao.updateById(settleWorkflowInstance);
                settleWorkflowStepInstance.setStepInstState(FlowContants.STEP_INST_STATUS_CANCEL);
                settleWorkflowStepInstance.setSuccessTime(new Date());
                settleWorkflowStepInstanceDao.updateById(settleWorkflowStepInstance);
                settleWorkflowInstanceLinkDao.remove(new LambdaQueryWrapper<SettleWorkflowInstanceLink>().eq(SettleWorkflowInstanceLink::getFromInstCode, cancelWorkflowReq.getInstCode()).or().eq(SettleWorkflowInstanceLink::getToInstCode, cancelWorkflowReq.getInstCode()));
                return "作废成功";
            } else {
                return "正在作废，请勿重复操作";
            }
        } catch (Exception e) {
            if (locked) {
                lockService.unlock(cancelWorkflowReq.getInstCode());
            }
        }
        return null;
    }

    @Override
    public WorkflowStepDataVo getStepData(WorkflowStepDataReq workflowStepDataReq) {
        String stepInstCode = workflowStepDataReq.getStepInstCode();
        SettleWorkflowStepInstance stepInstance = settleWorkflowStepInstanceDao.getOne(new LambdaQueryWrapper<SettleWorkflowStepInstance>().eq(SettleWorkflowStepInstance::getStepInstCode, stepInstCode));
        SettleWorkflow settleWorkflow = settleWorkflowDao.getOne(new LambdaQueryWrapper<SettleWorkflow>().eq(SettleWorkflow::getFlowCode, stepInstance.getFlowCode()));
        SettleWorkflowStep settleWorkflowStep = settleWorkflowStepDao.getOne(new LambdaQueryWrapper<SettleWorkflowStep>().eq(SettleWorkflowStep::getFlowCode, stepInstance.getFlowCode()).eq(SettleWorkflowStep::getStepCode, stepInstance.getStepCode()));
        AutoflowMain autoflowMain = autoflowMainDao.getOne(new LambdaQueryWrapper<AutoflowMain>().eq(AutoflowMain::getCode, stepInstance.getFlowCode()));
        AutoflowStep autoflowStep = autoflowStepDao.getOne(new LambdaQueryWrapper<AutoflowStep>().eq(AutoflowStep::getFlowId, autoflowMain.getId()).eq(AutoflowStep::getStepNo, stepInstance.getStepCode()));
        String modelCode = settleWorkflowStep.getModelCode();
        LambdaQueryWrapper<AutoflowStepForm> eq = new LambdaQueryWrapper<AutoflowStepForm>().eq(AutoflowStepForm::getStepId, autoflowStep.getId());
        List<String> useFormId = Arrays.asList(modelCode.split(","));
        eq.in(AutoflowStepForm::getFormId,useFormId);
        List<AutoflowStepForm> formList = autoflowStepFormDao.list(eq);
        List<WorkflowStepFormVo> workflowStepFormVos = new ArrayList<>();
        formList.forEach(line->{
            DiyForm form = formDao.getById(line.getFormId());
            WorkflowStepFormVo workflowStepFormVo = new WorkflowStepFormVo();
            workflowStepFormVo.setFormId(line.getFormId());
            workflowStepFormVo.setViewId(line.getViewId());
            workflowStepFormVo.setFormName(form.getName());
            workflowStepFormVos.add(workflowStepFormVo);
        });
        List<SettleBizform> settleBizform = getFlowStepForm(stepInstCode);
        WorkflowStepDataVo workflowStepDataVo = new WorkflowStepDataVo();
        workflowStepDataVo.setAutoflow(settleWorkflow);
        workflowStepDataVo.setAutoflowStep(settleWorkflowStep);
        workflowStepDataVo.setBizFormDetail(settleBizform);
        workflowStepDataVo.setFormList(workflowStepFormVos);
        return workflowStepDataVo;
    }



    public SettleBizform createByModeCode(String modelCode, String flowInsCode, String stepInsCode) {
        LambdaQueryWrapper<SettleBizmodel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SettleBizmodel::getModelCode,modelCode);
        SettleBizmodel settleBizmodel = settleBizmodelDao.getOne(queryWrapper);
        return createByModeCode(settleBizmodel,flowInsCode,stepInsCode);
    }
    public SettleBizform createByModeCode(SettleBizmodel bizmodel, String flowInsCode, String stepInsCode) {
        SettleBizform settleBizform = new SettleBizform();
        settleBizform.setCreateDate(new Date());
        settleBizform.setInstCode(flowInsCode);
        settleBizform.setStepInstCode(stepInsCode);
        settleBizform.setFormModelCode(bizmodel.getModelCode());
        settleBizform.setFormType(bizmodel.getFormType());
        settleBizform.setPrintNum(0);
        settleBizform.setState(1);
        settleBizform.setBizzTable(bizmodel.getBizzTable());
        return settleBizform;
    }

    /**
     * 获取表单的数据
     *
     * @param id
     * @return
     */
    @Override
    public Map<String, Object> getFormData(String tableName, Long id) {
        Map<String, Object> resultMap = new HashMap<>();
        //过滤器
        StringBuffer conditionSb = new StringBuffer("id ="+id);
        Map<String, Object> conditionMap = new LinkedHashMap<>();
        String sql = " SELECT * FROM " + tableName + " WHERE " + conditionSb;
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, conditionMap);;
        handleLongTypeProperty(list);
        if (CollectionUtil.isNotEmpty(list)){
            resultMap=list.get(0);
        }
        return resultMap;

    }

    @Override
    public SettleBizform saveData(WorkflowSaveDataReq jsonObject) {
        Long bizFormId = jsonObject.getBizFormId();
        Long businessId = jsonObject.getBusinessId();
        Object printData = jsonObject.getPrintData();
        SettleBizform bizFormDetail = null;
        Boolean locked = lockService.tryLock("saveForm:" + bizFormId, 5, 5 * 60, TimeUnit.SECONDS);
        if (locked) {
            try{
                bizFormDetail = saveForm(bizFormId, businessId,printData);
            } finally {
                lockService.unlock("saveForm:" + bizFormId);
            }
        }else {
            BusinessException.happen("正在保存中，请勿重复操作");
        }
        return bizFormDetail;
    }



    @Transactional(rollbackFor = Exception.class)
    public SettleBizform saveForm(Long id, Long businessId ,Object printData) {
        log.info("保存单据入参："+id+"{}"+businessId);
        //验证表单ID是否有效
        User user = Req.getCurrUser();
        if (user == null) {
            BusinessException.happen("未获取到登录人信息！");
        }
        SettleBizform settleBizform = settleBizformDao.getById(id);
        if(settleBizform==null) {
            BusinessException.happen("表单信息不存在");
        }
        //更新打印数据
        if(printData !=null) {
            settleBizform.setPrintData(JSONUtil.toJsonStr(printData));
        }else{
            settleBizform.setPrintData("{}");
        }
        if(settleBizform.getState() == FlowContants.SETTLE_BIZFORM_STATE_CREATED) {
            settleBizform.setState(FlowContants.SETTLE_BIZFORM_STATE_SAVED);
        }
        if(settleBizform.getBizFormId()==null){
            //不存在即新增
            //保存 SETTLE_BIZFORM
            settleBizform.setCreateDate(new Date());
            settleBizform.setBizFormId(businessId);
        }
        settleBizformDao.updateById(settleBizform);
        return settleBizform;
    }




    private boolean checkStr(String value){
        String arr[] = {"FJNR_HQZYZM_SL","FJNR_JSD_SL","FJNR_YSD_SL","FJNR_SLJDD_SL","FJNR_ZLJDD_SL","FJNR_CKD_SL","FJNR_RKD_SL","KSXZ_FJ","HTXS_FJ","XSLX_FJ","MTZL_FJ","YSFS_FJ","KSLX_FJ"};
        boolean b = false;
        for (String element : arr) {
            if (element.equals(value)) {
                b = true;
                break;
            }
        }
        return b;
    }

    @Override
    public  List<SettleBizform> getFlowStepForm(String stepInsCode) {
        List<SettleBizform> settleBizforms = new ArrayList<>();
        SettleWorkflowStepInstance stepInstance = settleWorkflowStepInstanceDao.getOne(new LambdaQueryWrapper<SettleWorkflowStepInstance>().eq(SettleWorkflowStepInstance::getStepInstCode, stepInsCode));
        SettleWorkflowStep settleWorkflowStep = settleWorkflowStepDao.getOne(new LambdaQueryWrapper<SettleWorkflowStep>().eq(SettleWorkflowStep::getFlowCode, stepInstance.getFlowCode()).eq(SettleWorkflowStep::getStepCode, stepInstance.getStepCode()));
        AutoflowMain autoflowMain = autoflowMainDao.getOne(new LambdaQueryWrapper<AutoflowMain>().eq(AutoflowMain::getCode, stepInstance.getFlowCode()));
        AutoflowStep autoflowStep = autoflowStepDao.getOne(new LambdaQueryWrapper<AutoflowStep>().eq(AutoflowStep::getFlowId, autoflowMain.getId()).eq(AutoflowStep::getStepNo, stepInstance.getStepCode()));
        String modelCode = settleWorkflowStep.getModelCode();
        LambdaQueryWrapper<AutoflowStepForm> eq = new LambdaQueryWrapper<AutoflowStepForm>().eq(AutoflowStepForm::getStepId, autoflowStep.getId());
        List<String> useFormId = Arrays.asList(modelCode.split(","));
        eq.in(AutoflowStepForm::getFormId,useFormId);
        List<AutoflowStepForm> list = autoflowStepFormDao.list(eq);
        list.forEach(stepForm->{
            SettleBizform settleBizform = settleBizformDao.getOne(new LambdaQueryWrapper<SettleBizform>().eq(SettleBizform::getStepInstCode, stepInsCode).eq(SettleBizform::getFormId,stepForm.getFormId()));
            if (ObjectUtil.isEmpty(settleBizform)){
                settleBizform = createByModeCode(stepForm.getFormId()+"",stepInstance.getInstCode(),stepInstance.getStepDesc());
                //不是最后一个环节 拷贝上一次提交的pdf
                List<Map<String, String>> previousPdfs =workflowInstanceMapper.selectLastPdf(stepInstance.getInstCode(), settleBizform.getFormModelCode());
                if (!CollectionUtils.isEmpty(previousPdfs)) {
                    Map<String, String> previousPdf = previousPdfs.get(0);
                    String pdfFilePath = previousPdf.get("PDF_FILE_PATH");
                    settleBizform.setPdfFilePath(pdfFilePath);
                    settleBizform.setPdfFileName(previousPdf.get("PDF_FILE_NAME"));
                }
                settleBizform.setFormId(stepForm.getFormId());
                settleBizform.setStepInstCode(stepInsCode);
                settleBizformDao.save(settleBizform);
            } else{
                if(StringUtils.isBlank(settleBizform.getPdfFilePath())) {
                    List<Map<String, String>> previousPdfs =workflowInstanceMapper.selectLastPdf(stepInstance.getInstCode(), settleBizform.getFormModelCode());
                    if (!CollectionUtils.isEmpty(previousPdfs)) {
                        Map<String, String> previousPdf = previousPdfs.get(0);
                        String pdfFilePath = previousPdf.get("PDF_FILE_PATH");
                        settleBizform.setPdfFilePath(pdfFilePath);
                        settleBizform.setPdfFileName(previousPdf.get("PDF_FILE_NAME"));
                    }
                }
            }
            //如果自己的bizformid 是空的 向前获取最后一条bizformid
//            if(settleBizform.getBizFormId()==null) {
//                List<SettleBizform> map =workflowInstanceMapper.selectLastBizFrom(stepInstance.getInstCode(), settleBizform.getFormModelCode(), settleBizform.getId());
//                if(!CollectionUtils.isEmpty(map)) {
//                    settleBizform.setBizFormId(map.get(0).getBizFormId());
//                }
//            }
            if(settleBizform.getState()<FlowContants.SETTLE_BIZFORM_STATE_PDFED && settleBizform.getPdfFilePath()!=null) {
                settleBizform.setState(FlowContants.SETTLE_BIZFORM_STATE_PDFED);
            }
            settleBizforms.add(settleBizform);
        });
        return settleBizforms;
    }

    @Override
    public SettleBizform makePdf(WorkflowMakePdfReq req) {
        String imgPath = req.getImgPath();
        Long bizFormId = req.getBizFormId();
        SettleBizform flowStepForm = settleBizformDao.getById(bizFormId);
        if (flowStepForm.getBizFormId() == null) {
           BusinessException.happen("还未保存单据，不能生成文件");
        }
        MakePdfResult makePdfResult = null;
        try {
            makePdfResult = doStrategy(flowStepForm, imgPath);
            flowStepForm.setPdfFilePath(makePdfResult.getFilePath());
            flowStepForm.setState(3);
            settleBizformDao.updateById(flowStepForm);
        } catch (InfoException infoException) {
            throw infoException;
        } catch (Exception infoException) {
            infoException.printStackTrace();
            throw new InfoException("未知异常，请检查网络等信息");
        } finally {
            if (makePdfResult != null) {
                for (File f : makePdfResult.getPadfpaths()) {
                    if (f.exists()) {
                        f.delete();
                    }
                }
                //移除临时文件
                if (makePdfResult.getFile().exists()) {
                    makePdfResult.getFile().delete();
                }
                if (makePdfResult.getThumbnailSourceFile().exists()) {
                    makePdfResult.getThumbnailSourceFile().delete();
                }
            }
        }
        return flowStepForm;
    }


    private MakePdfResult doStrategy(SettleBizform settleBizform,  String imgPath) {
        MakePdfResult makePdfResult=new MakePdfResult();
        MakePdfData makePdfData = getMakePdfData( settleBizform);
        makePdfResult.setAutoformMaimType(makePdfData.autoformMaim.getCode());
        String pdf_file_name = makePdfData.autoformMaim.getName();
        //挨个生成正文的pdf
        List<File> padfpaths = new ArrayList<>();
        for ( DiyTmplFile template : makePdfData.formTemplates) {
            if (template.getType().equals("word")) {
                File path = pdfByWord(imgPath, template.getUrl(), makePdfData.bizMap, makePdfData.stringAutoformColumnMap);
                padfpaths.add(path);
            } else if (template.getType().equals("excel")) {
                File path = pdfByXls(template.getUrl(), makePdfData.bizMap);
                padfpaths.add(path);
            } else if (template.getType().equals("placeholder")) {
                FileToPdf(imgPath, makePdfData.stringAutoformColumnMap, makePdfData.bizMap, template, padfpaths);
            }
        }
        File pdfTempFile = new File("tempFile/" +  IdUtil.nextIdStr() + ".pdf");
        pdfTempFile = PdfUtils.mergePdfFile(padfpaths, pdfTempFile);
        String pdf_file_path=null;
        try {
            MultipartFile pdfMultipartFile = new ConvertMultipartFile(pdfTempFile, "file.pdf", "file.pdf", "application/pdf");
            pdf_file_path =  minioService.upload(pdfMultipartFile);
        } catch (Exception e) {
            throw new InfoException("上传失败");
        }
//        if (CollectionUtil.isNotEmpty(padfpaths)){
//            padfpaths.forEach(line->{
//                if (line != null){
//                    try {
//                        line.delete();
//                    }catch (Exception e){
//                    }
//                }
//            });
//        }
        //缩略图
        makePdfResult.setFileName(pdf_file_name);
        makePdfResult.setFilePath(pdf_file_path);
        makePdfResult.setFile(pdfTempFile);
        makePdfResult.setPadfpaths(padfpaths);
        makePdfResult.setThumbnailSourceFile(padfpaths.get(0));
        return makePdfResult;
    }

    private void FileToPdf(String imgPath, Map<String, DiyColumn> stringAutoformColumnMap, Map bizMap, DiyTmplFile template, List<File> padfpaths) {
        String templateName = template.getName();
        DiyColumn column = stringAutoformColumnMap.get(templateName);
        if (column == null) {
            return;
        }

        switch (column.getDataType()) {
            case "图片":
                break;
            default:
                return;
        }
        try {
            String valueStr = MT.getMapstr(column.getCode(), bizMap);
            String[] values = valueStr.split(",");
            for (String value : values) {
                //判断类型
                String[] split = value.split("\\.");
                if (split.length <= 1) {
                    continue;
                }
                String leixing = split[1];
                String filePath = imgPath + value;
                switch (leixing) {
                    case "jpeg":
                    case "jpg":
                    case "png":
                    case "gif": {
                        File file = PdfUtils.imgToPdf(new URL(filePath));
                        padfpaths.add(file);
                    }
                    break;
                    default:
                        continue;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private File pdfByWord(String imgPath, String templatePath, Map bizMap, Map<String, DiyColumn> autoFormColumnList) {
        if (StringUtils.isEmpty(templatePath)) {
            throw new InfoException("表单尚未配置正文模板，请检查智能化设置");
        }
        try {
            String[] fileFullNames = templatePath.split("/");
            String fileFullName = fileFullNames[fileFullNames.length - 1];
            File tempFile = new File("tempFile/" + fileFullName);
            if (!tempFile.exists()) {
                tempFile = FileDown.downloadFile(excelModelRemotePath +templatePath, "tempFile");
            }
            //  生成pdf
            //先把读进来的图片放到一个ByteArrayOutputStream中，以便产生ByteArray
            // 获取文件的名称，又可能是多个，需要根据,(逗号)进行分割
            File pdfTempFile = Word2PdfUtilExtend.doc2pdfNew(new FileInputStream(tempFile), imgPath, autoFormColumnList, bizMap);
            if (pdfTempFile == null) {
                throw new InfoException("生成正文模板失败，请联系开发人员检查文件服务器是否正常");
            }

            return pdfTempFile;
        } catch (Exception e) {
            e.printStackTrace();
            throw new InfoException("正文模板数据注入异常，请检查数据是否存在特殊字符等问题");
        }

    }


    public File pdfByXls(String templatePath, Map bizMap) {
        if (StringUtils.isEmpty(templatePath)) {
            throw new InfoException("表单尚未配置正文模板，请检查智能化设置");
        }
        File excelTempFile = createExcell(bizMap, templatePath);
        if (excelTempFile == null) {
            throw new InfoException("生成正文模板失败，请联系开发人员检查文件服务器是否正常");
        }
        //转换成pdf临时文件 临时文件不需要定死路径不需要固定名字，不用整那些公共路径参数
        File pdfTempFile = PdfUtils.transExcelToPdf(excelTempFile);
        if (pdfTempFile == null) {
            throw new InfoException("pdf生成失败");
        }
        if (excelTempFile.exists()) {
            excelTempFile.delete();
        }
        return pdfTempFile;
    }

    public File createExcell(Map<String, Object> map, String modelFilePath) {
        try {
            File excelFile = new File(RT.getRandomForWordInt(16) + ".xlsx");// 输出路径
            FileOutputStream outputStream = new FileOutputStream(excelFile);
            try {
                createExcell(map, modelFilePath, outputStream);
            } catch (Exception e) {
                throw e;
            } finally {
                outputStream.close();
            }
            return excelFile;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public void createExcell(Map<String, Object> map, String modelFilePath, OutputStream outputStream) {
        File modelFile = null;
        try {
            modelFile = FileDown.downloadFile(excelModelRemotePath+ modelFilePath, "tempFile");
            ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(outputStream).withTemplate(modelFile);
            ExcelWriter build = excelWriterBuilder.build();
            int numberOfSheets = build.writeContext().writeWorkbookHolder().getWorkbook().getNumberOfSheets();
            for (int i = 0; i < numberOfSheets; i++) {
                build.fill(map, excelWriterBuilder.sheet(i).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new InfoException("生成xls错误 请联系管理员");
        }finally {
            if (modelFile != null && modelFile.exists()) {
                modelFile.delete();
            }
        }
    }

    //获取用于生成打印表单的数据
    private MakePdfData getMakePdfData( SettleBizform flowStepForm) {
        DiyForm autoformMaim = diyFormDao.getById(flowStepForm.getFormId());
        if (autoformMaim == null) {
            throw new InfoException("表单内容模板不存在，请检查智能化设置！");
        }
        List<DiyTmpl> diyTmpls = diyTmplDao.list(new LambdaQueryWrapper<DiyTmpl>().eq(DiyTmpl::getFormId, autoformMaim.getId()).eq(DiyTmpl::getIsDefault, true));
        if (diyTmpls.size() == 0) {
            throw new InfoException("表单尚未配置正文模板，请检查智能化设置");
        }
        DiyTmpl diyTmpl = diyTmpls.get(0);
        List<DiyTmplFile> formTemplates = diyTmplFileDao.list(new LambdaQueryWrapper<DiyTmplFile>().eq(DiyTmplFile::getTmplId, diyTmpl.getId()).orderByAsc(DiyTmplFile::getSort));
        List<DiyColumn> autoFormColumnList = diyColumnDao.list(new LambdaQueryWrapper<DiyColumn>().eq(DiyColumn::getFormId,autoformMaim.getId()));
        Map<String, DiyColumn> stringAutoformColumnMap = CollectionUtils.collectionToMap(autoFormColumnList, DiyColumn::getCode);
        Long bizformId = flowStepForm.getBizFormId();
        Map bizMap = getFormData(flowStepForm.getBizzTable(),bizformId);
        log.info("生成文件所有数据为：{}", JSONUtil.toJsonStr(bizMap));
        if (bizMap == null) {
            throw new InfoException("表单数据未保存，无法生成正文！");
        }
        String printData = flowStepForm.getPrintData();
        //存下来的打印数据
        if (StringUtils.isNotBlank(printData)) {
            try {
                JSONObject jsonObject = JSON.parseObject(printData);
                bizMap.putAll(jsonObject);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        MakePdfData makePdfData = new MakePdfData();
        makePdfData.bizMap = bizMap;
        makePdfData.formTemplates = formTemplates;
        makePdfData.stringAutoformColumnMap = stringAutoformColumnMap;
        makePdfData.autoformMaim = autoformMaim;
        return makePdfData;
    }

    /**
     * 处理Long类型字段，转成字符串再传给前端，避免丢失精度
     */
    private void handleLongTypeProperty(List<Map<String, Object>> list) {
        String KEY = "ID";
        list.stream().forEach(m -> {
            m.put(KEY, String.valueOf(m.get(KEY)));
        });
    }
}
